package cscie160.project;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.UnknownHostException;
import java.rmi.server.UnicastRemoteObject;

public class Client extends UnicastRemoteObject implements ATMListener {

    public Client() throws RemoteException
    {
        super();
    }

    public void notify(TransactionNotification notification) throws RemoteException
    {
        System.out.println("Client received notification " + notification);
    }

    public static void testATM(ATM atm) {
        if (atm!=null) {
            System.out.println("Start tests");
            performTestOne(atm);
            performTestTwo(atm);
            performTestThree(atm);
            performTestFour(atm);
            performTestFive(atm);
            performTestSix(atm);
            performTestSeven(atm);
            performTestEight(atm);
            performTestNine(atm);
            printBalances(atm);
        }
    }
    public static void printBalances(ATM atm) {
        try {
            System.out.println("Balance(0000001): "+atm.getBalance(getAccountInfo(0000001, 1234)));
            System.out.println("Balance(0000002): "+atm.getBalance(getAccountInfo(0000002, 2345)));
            System.out.println("Balance(0000003): "+atm.getBalance(getAccountInfo(0000003, 3456)));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void performTestOne(ATM atm) {
        try {
            atm.getBalance(getAccountInfo(0000001, 5555));
        } catch (Exception e) {
            System.out.println("Failed as expected: "+e);
        }
        System.out.println("After test 1");
        printBalances(atm);
    }
    public static void performTestTwo(ATM atm) {
        try {
            atm.withdraw(getAccountInfo(0000002, 2345), 500);
        } catch (Exception e) {
            System.out.println("Failed as expected: "+e);
        }
        System.out.println("After test 2");
        printBalances(atm);
    }
    public static void performTestThree(ATM atm) {
        try {
            atm.withdraw(getAccountInfo(0000001, 1234), 50);
        } catch (Exception e) {
            System.out.println("Failed as expected: "+e);
        }
        System.out.println("After test 3");
        printBalances(atm);
    }
    public static void performTestFour(ATM atm) {
        try {
            atm.deposit(getAccountInfo(0000001, 1234), 500);
        } catch (Exception e) {
            System.out.println("Unexpected error: "+e);
        }
        System.out.println("After test 4");
        printBalances(atm);
    }
    public static void performTestFive(ATM atm) {
        try {
            atm.deposit(getAccountInfo(0000002, 2345), 100);
        } catch (Exception e) {
            System.out.println("Unexpected error: "+e);
        }
        System.out.println("After test 5");
        printBalances(atm);
    }
    public static void performTestSix(ATM atm) {
        try {
            atm.withdraw(getAccountInfo(0000001, 1234), 100);
        } catch (Exception e) {
            System.out.println("Unexpected error: "+e);
        }
        System.out.println("After test 6");
        printBalances(atm);
    }
    public static void performTestSeven(ATM atm) {
        try {
            atm.withdraw(getAccountInfo(0000003, 3456), 300);
        } catch (Exception e) {
            System.out.println("Unexpected error: "+e);
        }
        System.out.println("After test 7");
        printBalances(atm);
    }
    public static void performTestEight(ATM atm) {
        try {
            atm.withdraw(getAccountInfo(0000001, 1234), 200);
        } catch (Exception e) {
            System.out.println("Failed as expected: "+e);
        }
        System.out.println("After test 8");
        printBalances(atm);
    }
    public static void performTestNine(ATM atm) {
        try {
            atm.transfer(getAccountInfo(0000001, 1234),getAccountInfo(0000002, 2345), 100);
        } catch (Exception e) {
            System.out.println("Unexpected error: "+e);
        }
        System.out.println("After test 9");
        printBalances(atm);
    }

    private static AccountInfo getAccountInfo(int accountNumber, int PIN)
    {
        return new AccountInfo(accountNumber, PIN);
    }

    public static void main(String[] args) {
        try {
            Client myClient = new Client();
            System.out.println("Lookup atmfactory " + Naming.lookup("//localhost/atmfactory"));
            ATMFactory factory = (ATMFactory)Naming.lookup("//localhost/atmfactory");
            System.out.println("Got Factory");
            ATM atm = factory.getATM();
            System.out.println("Got ATM");
            if (atm!=null) {
                atm.addListener(myClient);
                System.out.println("Added listener");
                testATM(atm);
            }
        } catch (MalformedURLException mue) {
            mue.printStackTrace();
        } catch (NotBoundException nbe) {
            nbe.printStackTrace();
        } catch (UnknownHostException uhe) {
            uhe.printStackTrace();
        } catch (RemoteException re) {
            re.printStackTrace();
        }
    }
}